package com.charging.business.handle;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.charging.business.enums.Issuer;
import com.charging.business.exception.CustomizeException;
import com.charging.business.service.FeeExCpcHandle;
import com.charging.business.service.FeeExEtcObuHandle;
import com.charging.business.service.FeeExSpcHandle;
import com.charging.business.service.FeeNoCardHandle;
import com.charging.business.utils.*;
import com.charging.business.vo.BasicRequest;
import com.charging.business.vo.BasicResponse;
import com.charging.business.vo.FeeExCalcRequest;
import com.charging.business.vo.FeeExCalcResponse;
import com.charging.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 出口计费处理
 *
 * @author JerryLu
 * @date 2024/9/26 11:07
 */
@Component
@Slf4j
public class FeeExCalcHandle {
    private final static Logger logger = LoggerFactory.getLogger(FeeExCalcHandle.class);
    private final FeeExEtcObuHandle etcObuHandle;
    private final FeeExCpcHandle cpcHandle;
    private final FeeExEtcHandle etcHandle;
    private final FeeExSpcHandle spcHandle;
    private final FeeNoCardHandle noCardHandle;

    @Autowired
    public FeeExCalcHandle(FeeExEtcObuHandle etcObuHandle, FeeExCpcHandle cpcHandle, FeeExEtcHandle etcHandle,
                           FeeExSpcHandle spcHandle, FeeNoCardHandle noCardHandle)
    {
        this.etcObuHandle = etcObuHandle;
        this.cpcHandle = cpcHandle;
        this.etcHandle = etcHandle;
        this.spcHandle = spcHandle;
        this.noCardHandle = noCardHandle;
    }

    /**
     * 出口计费
     *
     * @param jsonObject
     * @return com.charging.business.vo.PublicReturn
     * @author JerryLu
     * @date 2024/9/26 11:08
     */
    public BasicResponse handle(JSONObject jsonObject) {
        BasicResponse result = new BasicResponse();
        FeeExCalcResponse response = new FeeExCalcResponse();
        BasicRequest basicRequest = JSON.parseObject(jsonObject.toString(), BasicRequest.class);
        FeeExCalcRequest request = JSON.parseObject(basicRequest.getBizContent(), FeeExCalcRequest.class);
        String msg = this.check(basicRequest, request);
        long start = 0L;
        if (!msg.isEmpty()) {
            response.setCode(-1);
            response.setCodeInfo(msg);
        } else {
            start = System.currentTimeMillis();
            try {
                switch (request.getMediaType()) {
                    // OBU/ETC
                    case 1:
                        if (request.getTransPayType() == 1) {
                            // 1-出口ETC通行
                            logVehicleExitInfo(request, "OBU天线", jsonObject);
                            response = this.etcObuHandle.run(request, response);
                        } else {
                            // 2-出口ETC刷卡通行
                            logVehicleExitInfo(request, "ETC单刷卡", jsonObject);
                            response = this.etcHandle.run(request, response);
                        }
                        break;
                    // CPC
                    case 2:
                        logVehicleExitInfo(request, "CPC刷卡", jsonObject);
                        response = this.cpcHandle.run(request, response);
                        break;
                    // 纸券
                    case 3:
                        logVehicleExitInfo(request, "纸卷", jsonObject);
                        response = this.spcHandle.run(request, response);
                        break;
                    // 无通行介质
                    case 9:
                        logVehicleExitInfo(request, "无通行介质特殊计费", jsonObject);
                        response = this.noCardHandle.run(request, response);
                        break;
                }
                if (request.getExStationHex().startsWith(Issuer.Issue140101.getProvinceCode())) {
                    response.setDiffState(null);
                } else if (request.getExStationHex().startsWith(Issuer.Issue610101.getProvinceCode())) {

                }
            } catch (CustomizeException e) {
                logger.error(e.getCustomMessage());
                response.setCode(-1);
                response.setCodeInfo(e.getCustomMessage());
                e.printStackTrace();
            } catch (Exception e) {
                logger.error(e.getMessage());
                response.setCode(-1);
                response.setCodeInfo(e.getMessage());
                e.printStackTrace();
            }
        }
        response.setMsgId(request.getMsgId());
        long end = System.currentTimeMillis();
        response.setCalCostTime((int) (end - start));
        response.setReceiveTime(DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_TT_HH_MM_SS));
        response.setSpecialType(BasicUtil.getSpecialInfo());
        result.setFilename(basicRequest.getFilename().replace("REQ", "RES"));
        result.setSign(basicRequest.getSign());
        result.setBizContent(JSON.toJSONString(response));
        if (response.getEtcFeeInfo() != null) {
            logger.info("-----计费完成,使用OBU设备内计费。");
        } else if (response.getCpcFeeInfo() != null) {
            logger.info("-----计费完成,使用CPC计费。");
        } else if (response.getOnlineFeeInfo() != null) {
            logger.info("-----计费完成,使用在线计费。");
        } else if (response.getOpenFeeInfo() != null) {
            logger.info("-----计费完成,使用开放式计费。");
        } else if (response.getMiniFeeInfo() != null) {
            logger.info("-----计费完成,使用兜底计费。");
        }
        return result;
    }

    /**
     * 交易前预检测
     *
     * @param basicRequest
     * @param request
     * @return
     */
    public String check(BasicRequest basicRequest, FeeExCalcRequest request) {
        String msg = "";
        if (basicRequest.getFilename().isEmpty()) {
            msg = "filename字段为null";
        } else if (basicRequest.getTimestamp().isEmpty()) {
            msg = "timestamp字段为null";
        } else if (!DateUtils.checkDate(basicRequest.getTimestamp())) {
            msg = "timestamp格式错误";
        } else if (basicRequest.getBizContent().isEmpty()) {
            msg = "bizContent字段为空";
        } else if (request.getTransPayType() == null) {
            msg = "transPayType字段为空";
        } else if (request.getMediaType() == 1) {
            if (request.getTransPayType() == 1) {
                if (request.getETCCARD0002().isEmpty()) {
                    msg = "ETCCARD0002字段为null";
                } else if (request.getETCCARD0015().isEmpty()) {
                    msg = "ETCCARD0015字段为null";
                } else if (request.getETCCARD0019().isEmpty()) {
                    msg = "ETCCARD0019字段为null";
                } else if (request.getOBUEF04().isEmpty()) {
                    msg = "OBUEF04字段为null";
                } else if (request.getOBUEF01().isEmpty()) {
                    msg = "OBUEF01字段为null";
                }
            } else if (request.getTransPayType() == 2) {
                if (request.getETCCARD0002().isEmpty()) {
                    msg = "ETCCARD0002字段为null";
                } else if (request.getETCCARD0015().isEmpty()) {
                    msg = "ETCCARD0015字段为null";
                } else if (request.getETCCARD0019().isEmpty()) {
                    msg = "ETCCARD0019字段为null";
                }
            }
        } else if (request.getMediaType() == 2) {
            if (request.getCPCMFEF01().isEmpty()) {
                msg = "CPCMFEF01字段为null";
            } else if (request.getCPCMFEF02().isEmpty()) {
                msg = "CPCMFEF02字段为null";
            } else if (request.getCPCEF01().isEmpty()) {
                msg = "CPCEF01字段为null";
            } else if (request.getCPCEF02().isEmpty()) {
                msg = "CPCEF02字段为null";
            } else if (request.getCPCEF04().isEmpty()) {
                msg = "CPCEF04字段为null";
            }
        }
        return msg;
    }

    private void logVehicleExitInfo(FeeExCalcRequest request, String operationType, JSONObject jsonObject) {
        logger.info("车辆[{}]到达出口,时间[{}],开始进行[{}]方式计费", request.getVehicleId(), DateUtils.convertTime(request.getExTime()), operationType);
        logger.info("请求原始json文件内容:{}", jsonObject);
    }
}
